package com.guilin.controller.front;


import com.guilin.common.config.RuoYiConfig;
import com.guilin.common.constant.Constants;
import com.guilin.common.core.domain.AjaxResult;
import com.guilin.common.exception.file.FileUploadException;
import com.guilin.common.utils.SecurityUtils;
import com.guilin.common.utils.StringUtils;
import com.guilin.common.utils.file.FileUploadUtils;
import com.guilin.common.utils.file.MimeTypeUtils;
import com.guilin.domain.Alumni;
import com.guilin.system.service.AlumniLoginService;
import com.guilin.system.service.AlumniService;
import com.guilin.system.service.ISysUserService;
import com.guilin.system.service.QQToKenService;
import com.guilin.vo.AlumniLoginVO;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.token.TokenService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;



/**
 * 校友前台
 */

@RestController
@RequestMapping("/alumni")
@Slf4j
public class AlumniControllerFront {


    @Autowired
    private AlumniLoginService alumniLoginService;

    @Autowired
    private QQToKenService qqtokenService;

    @Autowired
    private AlumniService alumniService;

    @Autowired
    private ISysUserService userService;

    @Value("${token.header}")
    private String header;


    /**
     * 获取校友信息
     *
     * @return
     */
    @GetMapping("/getInfo")
    public AjaxResult getInfo(HttpServletRequest request) {

        // 获取Token
        String token = qqtokenService.getToken(request);

        if (StringUtils.isEmpty(token)) {
            return AjaxResult.error("获取用户信息失败");
        }

        // 从Token中获取用户ID
        Claims claims = qqtokenService.parseToken(token);

        // Number是Integer和Long的共同父类 安全转换任何数字类型 避免JWT Token中存储时被自动序列化为Integer
        Number number = (Number) claims.get(Constants.ALUMNI_ID);
        Long alumniId = number.longValue();

        // 根据用户ID获取用户信息
        Alumni alumni = alumniService.selectAlumniById(alumniId);
        if (alumni == null) {
            return AjaxResult.error("校友不存在");
        }

        // 封装用户信息
        AlumniLoginVO alumniLoginVO = AlumniLoginVO.builder()
                .id(alumni.getId())
                .username(alumni.getUsername())
                .avatarUrl(alumni.getAvatarUrl())
                .alumniRole(alumni.getAlumniRole())
                .realName(alumni.getRealName())
                .email(alumni.getEmail())
                .major(alumni.getMajor())
                .sex(alumni.getSex())
                .phone(alumni.getPhone())
                .graduationYear(alumni.getGraduationYear())
                .graduationSchool(alumni.getGraduationSchool())
                .currentAddress(alumni.getCurrentAddress())
                .company(alumni.getCompany())
                .position(alumni.getPosition())
                .build();

        return AjaxResult.success(alumniLoginVO);
    }


    /**
     * 修改校友信息
     *
     * @param alumni
     * @return
     */
    @PutMapping("/updateAlumniInfo")
    public AjaxResult updateAlumniInfo(@RequestBody Alumni alumni) {

        // 调用服务层方法更新校友信息
        alumniService.updateAlumni(alumni);



        return AjaxResult.success("校友信息更新成功");
    }


    /**
     * 头像上传
     */
    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file, HttpServletRequest request) throws Exception {

        // 1.判断头像是否为空
        if (file.isEmpty()) {
            return AjaxResult.error("上传头像不能为空");
        }

        try {
            // 2.从请求头中获取Token
            String oldToken = qqtokenService.getToken(request);

            // 3.判断Token是否为空
            if (StringUtils.isEmpty(oldToken)) {
                return AjaxResult.error("未登录，上传头像失败");
            }

            // 4.解析Token
            Claims claims = qqtokenService.parseToken(oldToken);

            if (claims == null) {
                return AjaxResult.error("解析Token失败，上传头像失败");
            }

            // 5.从Token中获取用户ID
            Number alumniNumber = (Number) claims.get(Constants.ALUMNI_ID);

            if (alumniNumber == null) {
                return AjaxResult.error("获取用户ID失败，上传头像失败");
            }


            Long alumniId = alumniNumber.longValue();

            // 6.调用文件上传工具类进行头像上传
            String avatarUrl = FileUploadUtils.upload(
                    RuoYiConfig.getAvatarPath(),
                    file,
                    MimeTypeUtils.IMAGE_EXTENSION);

            // 7.更新校友头像
            Alumni alumni = new Alumni();
            alumni.setId(alumniId);
            alumni.setAvatarUrl(avatarUrl);
            boolean updateResult = alumniService.updateUserAvatar(alumni);

            // 8.判断更新结果
            if (!updateResult) {
                return AjaxResult.error("更新头像失败");
            }

            // 9.使旧令牌失效
            qqtokenService.invalidateOldToken(oldToken);

            // 10.生成包含新头像的令牌
            String newToken = qqtokenService.updateAvatarInToken(oldToken, avatarUrl);
            if (StringUtils.isEmpty(newToken)) {
                return AjaxResult.error("生成新令牌失败");
            }

            // 11.返回成功响应
            AjaxResult ajax = AjaxResult.success();
            ajax.put(Constants.ALUMNI_AVATAR, avatarUrl);
            ajax.put(Constants.TOKEN, newToken);
            ajax.put(Constants.ALUMNI_ID, alumniId);
            return ajax;
        } catch (FileUploadException e) {

            return AjaxResult.error("头像上传失败，请联系管理员");
        }

    }


    /**
     * 修改密码
     *
     * @param params
     * @return
     */
    @Transactional
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(@RequestBody Map<String, String> params) {
        String oldPassword = params.get("oldPassword");
        String newPassword = params.get("newPassword");
        String username = SecurityUtils.getUsername(); // 从安全上下文获取当前登录用户名

        // 1. 通过用户名查询校友信息
        Alumni alumni = alumniService.selectAlumniByUserName(username);
        if (alumni == null) {
            return AjaxResult.error("校友信息不存在");
        }

        // 2. 验证旧密码
        if (!SecurityUtils.matchesPassword(oldPassword, alumni.getPassword())) {
            return AjaxResult.error("旧密码验证失败");
        }

        // 3. 新密码不能与旧密码相同
        if (SecurityUtils.matchesPassword(newPassword, alumni.getPassword())) {
            return AjaxResult.error("新密码不能与旧密码相同");
        }

        // 4. 加密新密码
        String encryptedPwd = SecurityUtils.encryptPassword(newPassword);

        try {
            // 5. 更新sys_user系统用户表密码
            userService.resetUserPwd(username, encryptedPwd);

            // 6. 更新alumni校友表密码
            if (alumniService.updateAlumniPwd(alumni.getId(), encryptedPwd) > 0) {
                return AjaxResult.success("密码更新成功");
            }
            return AjaxResult.error("密码更新失败");
        } catch (Exception e) {
            log.error("密码更新异常", e);
            return AjaxResult.error("系统异常：" + e.getMessage());
        }
    }



    /**
     * 退出登录
     *
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public AjaxResult logout(HttpServletRequest request) {
        log.info("退出登录");

        try {
            // 1. 获取请求中的令牌
            String tokenHeader = request.getHeader(header);

            String token = null;
            if (tokenHeader.startsWith(Constants.TOKEN_PREFIX)) {
                token = tokenHeader.replace(Constants.TOKEN_PREFIX, "");
            } else {
                token = tokenHeader;
            }

            if (StringUtils.isNotEmpty(token)) {
                // 2. 验证令牌有效性
                if (qqtokenService.verifyToken(token)) {
                    // 3. 使令牌失效（加入黑名单）
                    qqtokenService.invalidateToken(token);
                    // 4. 从会话中移除用户信息
                    request.getSession().removeAttribute(Constants.ALUMNI_ID);
                    request.getSession().removeAttribute(Constants.ALUMNI_NAME);
                    request.getSession().removeAttribute(Constants.ALUMNI_ROLE);
                }
            }
            //使Session失效
            request.getSession().invalidate();
            return AjaxResult.success("退出登录成功");
        }catch (Exception e) {
            log.error("退出登录异常", e);
            return AjaxResult.error("退出登录失败");
        }
    }
}